package edu.mse.camel.client.uml.collab.emflistener;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;

import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;

import edu.mse.camel.client.core.events.model.ModelUpdateEvent;
import edu.mse.camel.client.core.events.model.ModelUpdateEvent.KIND;
import edu.mse.camel.client.core.idcache.ModelID;
import edu.mse.camel.client.core.idcache.SourceModelIDCache;

/**
 * @author darpan
 *
 */
public class Di2ContentAdapter extends CachingContentAdapter {

	private SourceModelIDCache sourceUMLModelIDCache;
	
	public Di2ContentAdapter(Diagram diagram, SourceModelIDCache sourceUMLModelIDCache) {
		super(diagram);
		this.sourceUMLModelIDCache = sourceUMLModelIDCache;
	}
	
	@Override
	protected void handleAdds(Notification notification, Object notifier) {
		if (notifier instanceof EObject) {
			ModelID modelID = modelIDCache.getID((EObject) notifier);
			if (modelID != null) {
				Object newValueObject = notification.getNewValue();
				ModelUpdateEvent me = EventUtil.createModelEvent(notification,
						modelID, ModelUpdateEvent.KIND.DI2, ModelUpdateEvent.EVENT_TYPE.ADD);
				if (newValueObject instanceof EObject) {
					EObject newValueEObject = (EObject) newValueObject;
					int featureID = notification.getFeatureID(notification.getFeature().getClass());
					cacheElement(newValueEObject);
					Resource resource =  
						new XMLResourceImpl(null);
					resource.getContents().add(EcoreUtil.copy(newValueEObject));
					try {
						ByteArrayOutputStream baos = new ByteArrayOutputStream();
						resource.save(baos, null);
						me.setByteArray(baos.toByteArray());
						me.setFeatureID(featureID);
						me.setElementModelID(modelIDCache.getID(newValueEObject));
						if (newValueEObject instanceof GraphElement) {
							Uml1SemanticModelBridge umlBridge = (Uml1SemanticModelBridge)
												((GraphElement) newValueEObject).getSemanticModel();
							if (((GraphElement) newValueEObject).getSemanticModel() != null) {
								me.setSemanticBridgeModelID(sourceUMLModelIDCache.getID(
										umlBridge.getElement()));
							}
						}
						publishEvent(me);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	@Override
	protected KIND getKind() {
		return ModelUpdateEvent.KIND.DI2;
	}
	
}
